/**
 * 工具函数模块
 * 
 * 包含项目创建过程中所需的各种实用工具函数，如模板分支计算、彩色输出、
 * 验证函数、README生成和IDE打开等功能
 */

import chalk from 'chalk';
const { red: _red, green: _green, yellow: _yellow, blue: _blue, magenta, cyan: _cyan, bold } = chalk;
import fsExtra from 'fs-extra';
const { writeFileSync } = fsExtra;
import { join, resolve } from 'path';
import { exec } from 'child_process';


/**
 * 计算模板分支名称
 * 
 * 根据模板类型和状态管理组合生成Git仓库分支名称
 * 用于从Git仓库获取对应类型的项目模板
 * 
 * @param {string} templateType - 模板类型 (only, min, normal, pro)
 * @param {string} stateManager - 状态管理类型 (state, GetX, Provider等)
 * @returns {string} 组合后的模板分支名称
 */
export function getTemplateBranch (templateType, stateManager) {
  if (stateManager == '') {
    return templateType;
  }
  return templateType + "-" + stateManager;
}

/**
 * 打印彩色文本到控制台
 * 
 * 支持多种颜色输出，用于区分不同类型的提示信息（成功、错误、警告等）
 * 使用chalk库实现颜色渲染，并自动添加粗体效果
 * 
 * @param {string} text - 要打印的文本内容
 * @param {string} color - 文本颜色，可选值: red, green, yellow, blue, purple, cyan
 */
export function printColored (text, color) {
  const colorMap = {
    red: _red,
    green: _green,
    yellow: _yellow,
    blue: _blue,
    purple: magenta,
    cyan: _cyan
  };

  console.log(bold(colorMap[color] ? colorMap[color](text) : text));
}

/**
 * 验证项目名称是否符合Flutter项目命名规范
 * 
 * Flutter要求项目名称必须以小写字母开头，只能包含小写字母、数字和下划线
 * 不符合规范时返回具体错误信息，符合时返回true
 * 
 * @param {string} name - 待验证的项目名称
 * @returns {boolean|string} 验证结果，true表示有效，字符串表示错误信息
 */
export function validateProjectName (name) {
  if (!name.match(/^[a-z][a-z0-9_]*$/)) {
    return '错误: 项目名称必须以小写字母开头，只能包含小写字母、数字和下划线';
  }
  return true;
}

/**
 * 验证包名是否符合Java包名规范
 * 
 * 包名必须以小写字母开头，可包含小写字母、数字、下划线和点号，点号用于分隔层级
 * 不符合规范时返回具体错误信息，符合时返回true
 * 
 * @param {string} name - 待验证的包名
 * @returns {boolean|string} 验证结果，true表示有效，字符串表示错误信息
 */
export function validatePackageName (name) {
  if (!name.match(/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/)) {
    return '错误: 包名必须符合Java包名规范，如com.example.myapp';
  }
  return true;
}

/**
 * 生成并更新项目的README.md文件
 * 
 * 创建包含项目基本信息和快速开始指南的README文件
 * 包含项目名称、创建日期、包名和基本命令说明
 * 
 * @param {string} targetDir - 项目根目录路径
 * @param {string} projectName - 项目名称
 * @param {string} packageName - 项目包名
 */
export function updateReadme (targetDir, projectName, packageName) {
  const currentDate = new Date().toISOString().split('T')[0];
  const readmePath = join(targetDir, 'README.md');

  const readmeContent = `# ${projectName}

基于火之夜工作室 Flutter 通用项目框架创建的应用

## 项目信息

- 项目名称: ${projectName}
- 包名: ${packageName}
- 创建日期: ${currentDate}

## 项目结构

- lib/: 主要代码目录
- assets/: 静态资源目录
- pubspec.yaml: 项目依赖配置

## 快速开始

\`\`\`bash
# 安装依赖
flutter pub get

# 运行项目 (默认调试模式)
flutter run

# 构建发布版本
flutter build appbundle
\`\`\`

## 功能特性

- 完整的项目结构
- 路由管理
- 主题管理
- 状态管理
- 网络请求封装
- 本地存储
`;

  writeFileSync(readmePath, readmeContent, 'utf8');
}

/**
 * 在指定IDE中自动打开项目
 * 
 * 根据用户选择的IDE类型和当前操作系统，执行相应的命令打开项目
 * 支持VS Code、Android Studio、文件管理器或手动打开
 * 
 * @param {string} targetDir - 项目根目录绝对路径
 * @param {string} [ideType="vscode"] - IDE类型，可选值: vscode, android_studio, open_folder, manual
 */
export function openProjectInIde (targetDir, ideType = "vscode") {
  const platform = process.platform;
  let command = null;

  // 确保路径是绝对路径
  targetDir = resolve(targetDir);

  switch (ideType) {
    case 'vscode':
      command = `code "${targetDir}"`;
      break;
    case 'android_studio':
      if (platform === 'darwin') { // macOS
        command = `open -a "Android Studio" "${targetDir}"`;
      } else if (platform === 'win32') { // Windows
        // 在Windows上查找Android Studio路径会比较复杂
        // 这里简化处理，实际应用中可能需要更复杂的逻辑
        command = '"C:\\Program Files\\Android\\Android Studio\\bin\\studio64.exe" "${targetDir}"';
      } else if (platform === 'linux') { // Linux
        command = `studio "${targetDir}"`;
      }
      break;
    case 'open_folder':
      if (platform === 'darwin') { // macOS
        command = `open "${targetDir}"`;
      } else if (platform === 'win32') { // Windows
        command = `explorer "${targetDir}"`;
      } else if (platform === 'linux') { // Linux
        command = `xdg-open "${targetDir}"`;
      }
      break;
    case 'manual':
      // 不执行任何命令
      return;
  }

  if (command) {
    try {
      exec(command, (error) => {
        if (error) {
          printColored(`无法打开IDE: ${error.message}`, 'yellow');
        }
      });
    } catch (e) {
      printColored(`打开IDE时发生错误: ${e.message}`, 'yellow');
    }
  }
}

